package utwente.sem.eindopdracht;
import java.util.ArrayList;
import java.util.List;

/**
 * Een Product is een ProductType dat door de fabriek kan worden gefabriceerd. Een Product kan bestaan
 * uit onderdelen of producten en bevat een Blauwdruk waarin staat vermeld hoe het Product gemaakt
 * dient te worden.
 * 
 * @author Richard Heijblom & Mark Wienk
 *
 */
public class Product extends ProductType {
	/**
	 * @clientCardinality 1
	 * @link aggregation
	 * @supplierCardinality *
	 */
	private List<ProductType> onderdelen;
	
	/**
	 * @clientCardinality 1
	 * @supplierCardinality 1
	 */
	
	private Blauwdruk blauwdruk;


	/**
	 * Een Product is een ProductType dat door de fabriek kan worden gefabriceerd. Een Product kan bestaan
	 * uit onderdelen of producten en bevat een Blauwdruk waarin staat vermeld hoe het Product gemaakt
	 * dient te worden.
	 */
	public Product() {
		onderdelen = new ArrayList<ProductType>();
		blauwdruk  = new Blauwdruk();
	}

	/**
	 * Verkrijg de blauwdruk van het Product
	 * @return blauwdruk
	 */
	public Blauwdruk getBlauwdruk() {
		return this.blauwdruk;
	}
	
	/**
	 * Stel een nieuwe Blauwdruk in bij het Product 
	 * @param blauwdruk
	 */
	public void setBlauwdruk(Blauwdruk blauwdruk){
		this.blauwdruk = blauwdruk;
	}
	
	/**
	 * Verkrijg de componenten van een Product (andere producten of onderdelen).
	 * @return een lijst met ProductType elementen (onderdelen of producten).
	 */
	public List<ProductType> getOnderdelen(){
		return this.onderdelen;
	}
	
	/**
	 * Voeg een onderdeel toe aan de specificatie van het product.
	 * @param p
	 */
	public void addOnderdeel(ProductType p) {
		this.onderdelen.add(p);
	}
	
	/**
	 * Laat een menu zien met alle opties voor de componenten van een product.
	 */
	public void showOnderdelenWizard() {
		String[] keuzeOpties = {
				"Terug naar het vorige menu",
				"Voeg component toe aan product",
				"Bekijk component van het product",
				"Verwijder componenten van het product",
				"Naar het onderdelen menu"
		};
		List<ProductType> componenten = new ArrayList<ProductType>();
		componenten.addAll(Controller.getController().getOnderdelenLijst());
		componenten.addAll(Controller.getController().getProductenLijst());
		int id;
		switch(Tui.getUI().toonMenu("Kies uit het menu:", keuzeOpties)) {
		case 0:
			return;
		case 1:
			if(componenten.size() > 0) {
				id = Tui.getUI().toonMenu("Kies een component om toe te voegen aan het product", componenten.toArray());
				addOnderdeel(componenten.get(id));
			} else {
				Tui.getUI().toonBericht("Er zijn nog geen componenten (producten of onderdelen) bekend, maak deze eerst aan.");
			}
			showOnderdelenWizard();
			break;
		case 2:
			Tui.getUI().toonLijst("De volgende componenten zijn in het systeem bekend voor dit product", onderdelen.toArray());
			showOnderdelenWizard();
			break;
		case 3:
			if(componenten.size() > 0) {
				id = Tui.getUI().toonMenu("Geef een component id op:", onderdelen.toArray());
				onderdelen.remove(id);
			} else {
				Tui.getUI().toonBericht("Geen componenten aanwezig");
			}
			showOnderdelenWizard();
			break;
		case 4:
			Onderdeel.showMenu();
			showOnderdelenWizard();
		}
	}
	
	/**
	 * Geef een wizard voor het bewerken van de Product velden.
	 */
	public void showProductWizard() {
		String[] keuzeOpties = {
			"Terug naar het vorige menu",
			"Bekijk/wijzig naam",
			"Bekijk/wijzig componenten",
			"Bekijk/wijzig blauwdruk"
		};
		switch(Tui.getUI().toonMenu("Geef aan wat u wilt toevoegen", keuzeOpties)) {
			case 0:
				return;
			case 1:
				Tui.getUI().toonBericht("De huidige naam is: " + this.name);
				Tui.getUI().toonBericht("Geef een nieuwe naam op (of laat het veld leeg om het ongewijzigd te laten): " + this.name);
				String invoer = Tui.getUI().getTekstInvoer();
				this.name = invoer.equals("") ? this.name : invoer;
				showProductWizard();
				break;
			case 2:
				showOnderdelenWizard();
				showProductWizard();
				break;
			case 3:
				blauwdruk.showMenu();
				showProductWizard();
				break;
		}
	}
	
	/**
	 * Geef een menu met CRUD acties voor Producten.
	 */
	public static void showMenu() {
		Tui.getUI().toonBericht("Product menu");
		String[] keuzeOpties = {
				"Terug naar het vorige menu",
				"Nieuw product",
				"Bekijk producten",
				"Wijzig product",
				"Verwijder product"
		};
		int id;
		switch(Tui.getUI().toonMenu("Maak een keuze uit het menu", keuzeOpties)) {
			case 0:
				return;
			case 1:
				Product product = new Product();
				product.showProductWizard();
				Controller.getController().getProductenLijst().add(product);
				Tui.getUI().toonBericht("Product succesvol aangemaakt.");
				showMenu();
				break;
			case 2:
				Tui.getUI().toonLijst("De volgende producten zijn in het systeem bekend:", Controller.getController().getProductenLijst().toArray());
				Tui.getUI().toonBericht("");
				showMenu();
				break;
			case 3:
				if(Controller.getController().getProductenLijst().size() > 0) {
					id = Tui.getUI().toonMenu("Geef een product id op", Controller.getController().getOnderdelenLijst().toArray());
					Controller.getController().getProductenLijst().get(id).showProductWizard();
				} else {
					Tui.getUI().toonBericht("Geen producten aanwezig");
				}
				showMenu();
				break;
			case 4:
				if(Controller.getController().getProductenLijst().size() > 0) {
					id = Tui.getUI().toonMenu("Geef een product id op", Controller.getController().getProductenLijst().toArray());
					//Verwijder gekoppelde product runs.
					for(ProductRun run : Controller.getController().getProductRunLijst()) {
						if (run.getProduct() == Controller.getController().getProductenLijst().get(id)) {
							Controller.getController().getProductRunLijst().remove(run);
						}
					}
					//Verwijder product zelf.
					Controller.getController().getProductenLijst().remove(id);
					Tui.getUI().toonBericht("Product & Product runs succesvol verwijderd");
				} else {
					Tui.getUI().toonBericht("Geen producten aanwezig");
				}
				showMenu();
				break;
		}
	}
}
